package traveldream.ejb.usermanagement;

import java.util.ArrayList;
import java.util.List;

import javax.annotation.Resource;
import javax.annotation.security.RolesAllowed;
import javax.ejb.EJBContext;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;

import org.apache.commons.codec.digest.DigestUtils;

import traveldream.ejb.packetmanagement.PacchettoViaggio;
import traveldream.ejb.packetmanagement.dto.PacketDTO;
import traveldream.ejb.usermanagement.dto.UserDTO;

/**
 * Session Bean implementation class UserBean
 */
@Stateless
public class UserMgrBean implements UserMgr {

	@PersistenceContext
    private EntityManager em;
	
	@Resource
	private EJBContext context;
	

	@Override
	public long save(UserDTO user) {
		Query q;
		q = em.createNamedQuery(User.FIND_BY_MAIL, User.class);
		q.setParameter(1, user.getEmail());
		List<UserDTO> resList= q.getResultList();
		if(resList.size() > 0)
			return -1;
		else{
			User newUser = new User(user);
			List<Group> groups = new ArrayList<Group>();
			groups.add(Group.USER);
			newUser.setGroups(groups);
			em.persist(newUser);
			em.flush();
			return newUser.getCID();
			}
	}


	@Override
	@RolesAllowed({Group._USER,Group._EMPLOYEE})
	public void update(UserDTO user) {
		
		em.merge(DTOtoClass(user));
	}


	@Override
	@RolesAllowed({Group._USER,Group._EMPLOYEE})
	public UserDTO getUserDTO() {
		UserDTO userDTO = convertToDTO(getPrincipalUser());
		return userDTO;
	}


	@Override
	@RolesAllowed({Group._USER})
	public void unregister() {
		remove(getPrincipalUser());
	}


	public User find(long cid) {
    	return em.find(User.class, cid);
    }
    
    public List<User> getAllUsers() {
    	return em.createNamedQuery(User.FIND_ALL, User.class)
                .getResultList();
    }

    public void remove(long cid) {
		User user = find(cid);
        em.remove(user);
	}
    
    public void remove(User user) {
    	em.remove(user);
	}
    
    
    public User getPrincipalUser() {
    	return find(Long.parseLong(getPrincipalCID()));
    }
    
    public String getPrincipalCID() {
    	return context.getCallerPrincipal().getName();
    }

    private UserDTO convertToDTO(User user) {
		UserDTO userDTO = new UserDTO();
		userDTO.setCid(user.getCID());
		userDTO.setEmail(user.getEmail());
		userDTO.setFirstName(user.getFirstName());
		userDTO.setLastName(user.getLastName());
		userDTO.setPassword(DigestUtils.sha512Hex(user.getPassword().getBytes()));
		return userDTO;
	}
    
    private User DTOtoClass(UserDTO userDTO){
    	User user = getPrincipalUser();
    	user.setEmail(userDTO.getEmail());
    	user.setFirstName(userDTO.getFirstName());
    	user.setLastName(userDTO.getLastName());
    	user.setPassword(DigestUtils.sha512Hex(userDTO.getPassword()));
    	return user;
    }
    
    @Override
    public void prenotazione(PacketDTO packetDTO){
    	User user = getPrincipalUser();
    	Query q = em.createNamedQuery(PacchettoViaggio.FIND_BY_PID, PacchettoViaggio.class);
    	q.setParameter(1, packetDTO.getPid());
    	List<PacchettoViaggio> resList = q.getResultList();
    	user.getPrenotazioni().add(resList.get(0));
    	em.merge(user);
    }


	@Override
	public boolean isBooked(PacketDTO packetDTO) {
		User user = getPrincipalUser();
		Query q = em.createNamedQuery(PacchettoViaggio.FIND_BY_PID, PacchettoViaggio.class);
		q.setParameter(1, packetDTO.getPid());
    	List<PacchettoViaggio> resList = q.getResultList();
    	for(int i=0; i<user.getPrenotazioni().size(); i++){
    		if(user.getPrenotazioni().get(i).equals(resList.get(0)))
    			return true;
    	}
		return false;
	}


	@Override
	public List<Long> ottieniPidsPrenotazioni() {
		List<Long> pidsToReturn = new ArrayList<Long>();
		User user = getPrincipalUser();
		for(int i=0; i<user.getPrenotazioni().size(); i++){
			pidsToReturn.add(user.getPrenotazioni().get(i).getPID());
		}
		return pidsToReturn;
	}
    
}
